<template>
  <div
    v-loading="state.loading || isLoading"
    :element-loading-background="state.elementLoadingBackground"
    style="width: 100%"
  >
    <el-select
      :class="{ 'no-wrap': noWrap }"
      style="width: 100%"
      v-bind="$attrs"
      v-model="state.paramVal"
      :placeholder="
        (typeof $attrs.disabled !== 'undefined' && $attrs.disabled !== false) ||
        state.formView
          ? ''
          : $attrs.placeholder
            ? $attrs.placeholder
            : `请选择${label}`
      "
      :clearable="isValue($attrs.clearable) ? $attrs.clearable : true"
      :filterable="isValue($attrs.filterable) ? $attrs.filterable : true"
      @change="handleChange"
      :title="
        $attrs.multiple !== undefined
          ? state.paramVal?.map?.((v) => optionsMapCpt.get(v)?.[labelKey])
          : optionsMapCpt.get(state.paramVal)?.[labelKey]
      "
      :disabled="isValue($attrs.disabled) ? $attrs.disabled : state.formView"
      :teleported="isValue($attrs.teleported) ? $attrs.teleported : true"
    >
      <slot v-if="$slots.default">
        <el-option
          v-for="item in options"
          :key="item[valueKey]"
          :label="item[labelKey]"
          :value="item[valueKey]"
          :title="item[labelKey]"
        />
      </slot>
    </el-select>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  onMounted,
  reactive,
  watch,
  getCurrentInstance,
  ComponentInternalInstance,
  inject,
} from 'vue'
import { isValue } from '@/utils/czr-util'
const emit = defineEmits(['emitParam', 'getObject'])
const props = defineProps({
  param: {},
  label: {},
  options: { type: Array, default: () => [] },
  labelKey: { type: String, default: 'label' },
  valueKey: { type: String, default: 'value' },
  static: { default: false },
  isLoading: { default: false },
  noWrap: { default: false },
  split: { default: null },
})
const attrs = (getCurrentInstance() as ComponentInternalInstance).attrs
const state = reactive({
  paramVal: props.param,
  loading: true,
  elementLoadingBackground: inject('element-loading-background', null),
  formView: inject('form-view', false),
})
watch(
  () => state.paramVal,
  (n: any) => {
    if (attrs.multiple !== undefined && props.split) {
      emit('emitParam', n ? n.join(props.split) : n)
    } else {
      emit('emitParam', n)
    }
  },
)
watch(
  () => props.param,
  (n: any) => {
    if (attrs.multiple !== undefined && props.split) {
      state.paramVal = n ? n.split(props.split) : n
    } else {
      state.paramVal = n
    }
  },
  { immediate: true },
)
watch(
  () => [props.options, props.static],
  () => {
    state.loading = false
  },
)
const optionsMapCpt = computed(() => {
  const map = new Map()
  props.options?.forEach((v: any) => {
    map.set(v[props.valueKey], v)
  })
  return map
})
const handleChange = (val: any) => {
  emit(
    'getObject',
    attrs.multiple === undefined
      ? optionsMapCpt.value.get(val)
      : val.map((v) => optionsMapCpt.value.get(v)),
  )
}
onMounted(() => {
  if (props.static !== false || props.options?.length > 0) {
    state.loading = false
  }
})
</script>

<style scoped lang="scss">
:deep(.no-wrap) {
  .el-select__selection {
    flex-wrap: unset;
  }
}
</style>
